package tech.yunland.shop.domain.dao;

import com.moyuer.bsf.domain.dao.BaseDao;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import tech.yunland.shop.domain.model.SN;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 流水号生成器
 *
 * @author: 袁首京<yuanshoujing@gmail.com>
 * @date: 15/8/16
 */
@Repository
public class SNGenerator extends BaseDao<SN, String> {

    /**
     * 根据关键字及机构生成流水号
     *
     * @param key     关键字
     * @param organId 机构标识
     * @return
     */
    public String gen(String key, String organId) {
        return gen(key, organId, new Date());
    }

    /**
     * 根据关键字，业务日期生成流水号
     *
     * @param key     关键字
     * @param organId 机构标识
     * @param bizDate 业务日期
     * @return
     */
    public String gen(String key, String organId, Date bizDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(bizDate);

        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;

        return gen(key, organId, year, month);
    }

    /**
     * 根据关键字、年份、月份生成流水号
     *
     * @param key     关键字
     * @param organId 机构标识
     * @param year    年
     * @param month   月
     * @return
     */
    public String gen(String key, String organId, int year, int month) {

        String result = null; // 返回结果

        DetachedCriteria criteria = DetachedCriteria.forClass(SN.class);
        criteria.add(Restrictions.eq("key", key));
        criteria.add(Restrictions.eq("organId", organId));
        criteria.add(Restrictions.eq("year", year));
        criteria.add(Restrictions.eq("month", month));

        List<SN> snList = this.findByCriteria(criteria);

        // 有则返回编号，流水号加 1
        if (snList != null && snList.size() > 0) {
            SN sn = snList.get(0);
            result = sn.toString();
            sn.setNum(sn.getNum() + 1);
            this.update(sn);
            return result;
        }

        // 否则，看有没有其它机构其它年份或月份的编号规则
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(SN.class);
        detachedCriteria.add(Restrictions.eq("key", key));
        List<SN> temp = findByCriteria(detachedCriteria);

        if (temp == null || temp.size() < 1) {
            throw new RuntimeException("没有定义读取关键字为 " + key + " 的编号规则");
        }

        // 有则为当前月份生成编号规则
        SN n0 = temp.get(0);
        SN newNumber = new SN();
        newNumber.setKey(key);
        newNumber.setOrganId(organId);
        newNumber.setYear(year);
        newNumber.setMonth(month);
        newNumber.setNumSize(n0.getNumSize());
        newNumber.setPrefix(n0.getPrefix());
        newNumber.setNum(1);

        result = newNumber.toString();

        // 保存
        newNumber.setNum(2);
        this.save(newNumber);

        return result;
    }

}
